/**
 * @file    Functional.h
 * @brief   Defines and implements the \ref Functional module.
 *
 ****************************************************************************
 * \defgroup Functional Core-Functional
 *
 * Functional module consists in a set of structures, classes and methods,
 * provided for convenience and based on STL algorithms and functional.
 *
 * There are many examples of benefits, most common use-cases are:
 *  - find, count (validate) items which fits a condition (validated using an item's member function)
 *  - execute a pre-defined method on items (such as initialization, serialization, ..)
 *  - transform (remove, copy,..) items which fits a condition
 *
 *
 * Since STL containers are widely used by WOSH core and Framework, common
 * and duplicate code is replaced by higher level syntax (by style's point of view),
 * moreover it gains almost always a better performance than
 * classic implementation (such as using a std \c for-loop iteration).
 *
 *
 * Basically most implementation are used as an extended OOP version of
 * <a href="http://www.sgi.com/tech/stl/binder2nd.html">bind2nd function</a> and
 * <a href="http://www.sgi.com/tech/stl/ptr_fun.html">ptr_fun function</a>.
 *
 * Read more about \c Functors on <a href="http://www.sgi.com/tech/stl/functors.html">SGI reference</a>.
 *
 *
 * Even when using member function pointer (and templates), this architecture works pretty well with inheritance,
 * on most compilers the function points to the last derived class. In other words, if you declare a vector<Object*>
 * and you store some ObjectEx type (derived from Object and overriding its functions), the compiler will
 * select the expected implementation (latest in hierarchy tree).
 *
 *
 * @note Generic notes about most implementations:
 *  - with \c pair-containers (such as std::map), it works on SECOND (value).
 *    This is a sort of specialization because of the common use of pair-containers,
 *    where the Key (first) is usually a sort of primary key and the second (value)
 *    is the real object. In fact we usually work on the (value) object and search
 *    (lookup) against the primary key. Moreover, often (especially in WOSH) the key
 *    is someway reflected in the object itself, such as: map<string,Object*> storing
 *    pairs <Object::getName(), Object*>.
 *  - object (pointers or derefenced-rereferences) are validated against NULL pointers.
 *    No exceptions are thrown, but the element is skipped (or return false/invalid).
 *
 *
 * @note
 *  WOSH won't support C++0x, this kind of features (functional) is the highest
 *  abstraction level of the core, but since part of STL it's included and appreciated.
 *
 * @warning
 *  Functional architecture is \b new in WOSH and has been introduced in release 0.7 (byron),
 *  it may be subject of interface changes, which will affect almost any container-user.
 *
 *
 * Simple example:
 * @code
	std::vector<Object*> objects;
	objects2.push_back( new Object(NULL, "item1") );
	objects2.push_back( new Object(NULL, "item2") );
	std::vector<Object*>::iterator it;

	bool non_functional( const std::string& lookingForName ) {
		for(it=objects.begin(); it=objects.end(); ++it) {
			if ( *it == NULL ) continue;
			if ( (*it)->getName() == lookingForName ) {
				(*it)->myMethod();
				return true;
			 }
		 }
		return false;
	 }

	bool better( const std::string& lookingForName )
		it = std::find_if(objects.begin(), objects.end(),
							Functor_Validator<Object, const std::string&>(lookingForName, &Object::getName ) );
		if ( it == objects2.end() )
			return false;
		(*it)->myMethod();
		return true;
	}
 * @endcode
 *
 ****************************************************************************
 * @version 0.8.013 $Id: Functional.h 2828 2010-08-02 11:16:31Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_Functionals_H__
 #define __WOSH_Core_Functionals_H__

 #include <woshDefs.h>
 #include <functional>
 #include <algorithm>

 #include <core/Variant.h>


 #include <vector>

 #include <core/Serialization.h>
 #include <core/List.h>
 #include <core/Object.h>


namespace wosh {

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VALIDATOR

/**
 * @class   wosh::Functor_Validator
 * @brief   Unary predicate (functor validator) using member's function to evaluate the falsehood.
 ****************************************************************************
 * Typical context usage:
 *  - count items validating (direcly) some condition [ for_each(items) { if (item->foo()==value) ++count; } ]
 *  - find an item (iterator) which validates some condition [ find_if(items) { if (item->foo()==value) return item; } ]
 *
 * Syntax usage:
 * @verbatim
	Functor_Validator<OBJECT_TYPE, FUNCTION_RETURN_TYPE>(COMPARISON_VALUE, &OBJECT_TYPE::FUNCTION )
@endverbatim
 * Where:
 *  - \c OBJECT_TYPE is the type holded by input container: \c T if input container is vector<T> or vector<T*>
 *  - \c FUNCTION_RETURN_TYPE is the return type of the member \c FUNCTION (it must be \b exactly the same)
 *  - \c COMPARISON_VALUE is the 'real' value to be evaluated, such as a string, integer, generic class
 *  - \c OBJECT_TYPE::FUNCTION is the member function to be evaluated, \c member function means that it is hosted
 *       by the (current) item, it must return an type of \c FUNCTION_RETURN_TYPE and have no arguments.
 *       It may sound like a big restriction, but in most cases you want to extract a particular offered field
 *       such as getName(), getID() and so on.
 *
 *
 * Comparison is performed using standard operator== (derived classes may re-implement it).
 * Current item is validated against NULL pointer (they are skipped, no exceptions).
 *
 *
 * As standard unary boolean fuctors, it works with STL iterators. Tested with most common containers, such as:
 *  - array
 *  - vector<T>, vector<T*>
 *  - map<Key, Value>, map<Key, Value*>
 *
 * @note
 *  with \c pair-containers (such as std::map), \c OBJECT_TYPE is considered the \b second of the pair (value).
 *
 * Requirements:
 *  - std::unary_function (optional, but required) [std::functional]
 *  - std::pair [std::utility]
 *
 * Examples:
 * @code
	Bundle* foundItem( const std::string& bundle_name ) {
		vector<Bundle*>::const_iterator it = std::find_if(this->bundles.begin(), this->bundles.end(),
			Functor_Validator<Bundle, const std::string&>(bundle_name, &Bundle::getName ) );
		if ( it == this->bundles.end() )
			return NULL;
		return *it;
	 }

	void countItems() {
		std::map<std::string, Object> mapObjects;
		mapObjects["name1"] = Object(NULL, "not-found");
		mapObjects["name2"] = Object(NULL, "found");
		int mycount = (int) std::count_if(mapObjects.begin(), mapObjects.end(),
			Functor_Validator<Object, const std::string&>("found", &Object::getName ) );
	 }
 * @endcode
 * Note: passing 'const std::string&' as template argument reflects two aspects: first, it
 * is compliant to member function \c getName() (else it might be a problem on some compilers);
 * second and very important, it won't waste memory because of copy-on-assignement operations.
 *
 * @ingroup Functional
 ****************************************************************************
 * @version 1.04 $Id $
 * @date    Released Stable on 2010-03-01
 * @author  Alessandro Polo
 ****************************************************************************/
// Personal notes:
//  VALUE_TYPE is really required as template because of: comparison check, (even
//   forgetting about member function template declaration (MethodAppender) ).
//   Moreover it's a global field shared with iteration, passed as argument.
//  OBJECT_TYPE cannot be deduced by argument (member function).
template <class OBJECT_TYPE, typename VALUE_TYPE>
class Functor_Validator : public std::unary_function<OBJECT_TYPE, bool> 
 {
	public:
		typedef VALUE_TYPE (OBJECT_TYPE::*MethodValidatorSelector)(void) const;

		/**
		 * @brief  Explicit constructor, initialize the target (comparison) value and member function to be evaluated.
		 * @param value [in] the value to be compared, it should be passed as const reference/pointer (VALUE_TYPE).
		 * @param fptr [in] member function to be evaluated, as (type)definition it must return type \c VALUE_TYPE
		 *                  and have no arguments
		 */
		explicit Functor_Validator(VALUE_TYPE value, MethodValidatorSelector fptr )
			: targetValue(value), fSelectorPtr(fptr) { }

	public:
		/**
		 * @brief  handle \b (pointer) item of the Sequence (container) (such as vector<OBJECT_TYPE*>, list<OBJECT_TYPE*>)
		 * @param object [in] current item* of the list, passed by the iteration manager (as for_each, count_if, ..),
		 * @return true when return value of member function (for current item) validates global expected value (targetValue)
		 */
		bool operator() ( OBJECT_TYPE* object ) const {
			if ( object == NULL ) return false;
			return (this->targetValue == (object->*fSelectorPtr)() );
		 }
		/**
		 * @brief  handle \b (reference) item of the Sequence (container) (such as vector<OBJECT_TYPE>, list<OBJECT_TYPE>)
		 * @param object [in] current item& of the list, passed by the iteration manager (as for_each, count_if, ..),
		 * @return true when return value of member function (for current item) validates global expected value (targetValue)
		 */
		bool operator() ( OBJECT_TYPE& object ) const {
			if ( &object == NULL ) return false;
			return (this->targetValue == (object.*fSelectorPtr)() );
		 }

		/**
		 * @brief  handle \b (pointer) item of the Pair (Container) (such as map<whatever-type,OBJECT_TYPE*>), caller usually ignores map::KEY type.
		 * @param pair_obj [in] current pair of the map: using second field (which is a pointer), passed by the iteration manager (as for_each, count_if, ..),
		 * @return true when return value of member function (for current item) validates global expected value (targetValue)
		 * @note   OBJECT_TYPE must be the \b second (value) of the pair: map<whatever-type,OBJECT_TYPE*>
		 */
		template <class MAP_KEY>
		bool operator() ( std::pair<MAP_KEY,OBJECT_TYPE*>& pair_obj ) const {
			if ( pair_obj.second == NULL ) return false;
			return (this->targetValue == (pair_obj.second->*fSelectorPtr)() );
		 }
		/**
		 * @brief  handle \b (reference) item of the Pair (Container) (such as map<whatever-type,OBJECT_TYPE>), caller usually ignores map::KEY type.
		 * @param pair_obj [in] current pair of the map: using second field (which is a reference/object), passed by the iteration manager (as for_each, count_if, ..),
		 * @return true when return value of member function (for current item) validates global espected value (targetValue)
		 * @note   OBJECT_TYPE must be the \b second (value) of the pair: map<whatever-type,OBJECT_TYPE>
		 */
		template <class MAP_KEY>
		bool operator() ( std::pair<MAP_KEY,OBJECT_TYPE>& pair_obj ) const {
			if ( &pair_obj.second == NULL ) return false;
			return (this->targetValue == (pair_obj.second.*fSelectorPtr)() );
		 }

	private:
		VALUE_TYPE targetValue;					///< value to be compared
		MethodValidatorSelector fSelectorPtr;	///< member function to be called for comparison
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// VALIDATOR
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXECUTER
// EXECUTER, is it really required? will see
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXECUTER
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ADDER

/**
 * @class   wosh::Functor_Appender
 * @brief   Unary predicate (functor executer) using member's function to feed a global container.
 ****************************************************************************
 * Typical context usage:
 *  - get/copy a field from each item of a set (create a column where each row reflect an item)
 *  - extract an internal object (pointer) of each object in a list (clone Permission(s) of a set of items)
 *
 * Syntax usage:
 * @verbatim
	Functor_Appender<OUTPUT_CONTAINER_TYPE, OBJECT_TYPE, FUNCTION_RETURN_TYPE>(OUTPUT_CONTAINER, &OBJECT_TYPE::FUNCTION )
@endverbatim
 * Where:
 *  - \c OUTPUT_CONTAINER_TYPE is the type of the output container. May be templated (such as vector<std::string>) or class ass List
 *  - \c ITEM_OBJECT_TYPE is the type holded by input container: \c T if input container is vector<T> or vector<T*>
 *  - \c FUNCTION_RETURN_TYPE is the return type of the member \c FUNCTION (it must be \b exactly the same)
 *  - \c OUTPUT_CONTAINER is the Container to which elements are added, of the \c OUTPUT_CONTAINER_TYPE type.
 *       Note that it must be a WOSH Container type or STL Sequence container, since it must support \b push_back(T*), push_back(T&) calls.
 *       This is handled by common containers using template specification. Using this functor against a ListT<T*>
 *       will 'copy' the pointers, but using it on a List (in the standard way, passing const references)
 *       will deep-copy the objects and the list may implement an automatic casting/allocation (see List::push<>). 
 *  - \c OBJECT_TYPE::FUNCTION is the member function to be evaluated, \c member function means that it is hosted
 *       by the (current) item, it must return an type of \c FUNCTION_RETURN_TYPE and have no arguments.
 *       It may sound like a big restriction, but in most cases you want to extract a particular offered field
 *       such as getName(), getID() and so on.
 *
 *
 * Works with WOSH Containers because appending is perfomed calling \c push_back method.
 * Typically used with ListT<>, List
 *
 *
 * @note
 *  with \c pair-containers (such as std::map), \c OBJECT_TYPE is considered the \b second of the pair (value).
 *
 * Requirements:
 *  - std::unary_function (optional, but required) [std::functional]
 *  - std::pair [std::utility]
 *
 * Examples:
 * @code
	List* getNamesFromVector() {
		std::vector<Object*> objects;
		objects.push_back( new Object(NULL, "asdasd") );
		objects.push_back( new Object(NULL, "second") );
		List* objs = new List(objects.size());
		for_each( objects.begin(), objects.end(), Functor_Appender<List, Object, const std::string&>(objs, &Object::getName ) );
		return objs;
	 }
	void getIDsFromMap( std::vector<long>& output ) {
		std::map<std::string, Object*> objects3;
		objects["item0"] =  new Object(NULL, "hello");
		object["foo"] =  new Object(NULL, "world");
		for_each( objects.begin(), objects.end(), Functor_Appender<std::vector<long>, Object, long>(output, &Object::getID ) );
	 }

	void copyPermissionsFrom( ListT<Object*>& input, std::vector<Permission>& output ) {
		for_each( input.begin(), input.end(), Functor_Appender<std::vector<Permission>, Object, const Permission&>(output, &Object::getPermission ) );
	 }

 * @endcode
 *
 *
 * @ingroup Functional
 ****************************************************************************
 * @version 1.02 $Id $
 * @date    Released Stable on 2010-03-01
 * @author  Alessandro Polo
 ****************************************************************************/
// Personal notes:
//  TARGET_TYPE is required because it is global, moreover we can't implement a
//   partial specialization (really!?).
//  VALUE_TYPE is really required as template because of: member function template
//   declaration (MethodAppender) and also because argument of constructor. It's a
//   global field shared with iteration.
//  OBJECT_TYPE cannot be deduced by argument (member function).
template <class TARGET_TYPE, class OBJECT_TYPE, typename VALUE_TYPE>
class Functor_Appender : public std::unary_function<OBJECT_TYPE, void> 
 {
	public:
		typedef VALUE_TYPE (OBJECT_TYPE::*MethodAppender)(void) const;

		/**
		 * @brief  Explicit constructor, initialize the target container and member function to be evaluated.
		 * @param output [in] the target container (such as STL Sequence, wosh::ListT<>, wosh::List)
		 * @param fptr [in] member function to be evaluated, as (type)definition it must return type \c VALUE_TYPE
		 *                  and have no arguments
		 */
		explicit Functor_Appender(TARGET_TYPE& output, MethodAppender fptr )
			: targetContainer(output), fAppenderPtr(fptr) { }

	public:
		/**
		 * @brief  handle \b (pointer) item of the Sequence (container) (such as vector<OBJECT_TYPE*>, list<OBJECT_TYPE*>).
		 *         Execute the member function on current item and add (push_back) the value to the target container
		 * @param object [in] current item* of the list, passed by the iteration manager (as for_each, count_if, ..),
		 */
		void operator() ( OBJECT_TYPE* object ) const {
			if ( object == NULL ) return;
//			targetContainer.push_back<Variant>( (object->*fAppenderPtr)() );
		 }
		/**
		 * @brief  handle \b (reference) item of the Sequence (container) (such as vector<OBJECT_TYPE>, list<OBJECT_TYPE>).
		 *         Execute the member function on current item and add (push_back) the value to the target container
		 * @param object [in] current item& of the list, passed by the iteration manager (as for_each, count_if, ..),
		 */
		void operator() ( OBJECT_TYPE& object ) const {
			if ( &object == NULL ) return;
//			targetContainer.push_back<Variant>( (object.*fAppenderPtr)() );
		 }

		/**
		 * @brief  handle \b (pointer) item of the Pair (Container) (such as map<whatever-type,OBJECT_TYPE*>), caller usually ignores map::KEY type.
		 *         Execute the member function on current item and add (push_back) the value to the target container
		 * @param pair_obj [in] current pair of the map: using second field (which is a pointer), passed by the iteration manager (as for_each, count_if, ..),
		 * @note   OBJECT_TYPE must be the \b second (value) of the pair: map<whatever-type,OBJECT_TYPE*>
		 */
		template <class MAP_KEY>
		void operator() ( std::pair<MAP_KEY,OBJECT_TYPE*>& pair_obj ) const {
			if ( pair_obj.second == NULL ) return;
//			targetContainer.push_back<Variant>( (pair_obj.second->*fAppenderPtr)() );
		 }
		/**
		 * @brief  handle \b (reference) item of the Pair (Container) (such as map<whatever-type,OBJECT_TYPE>), caller usually ignores map::KEY type.
		 *         Execute the member function on current item and add (push_back) the value to the target container
		 * @param pair_obj [in] current pair of the map: using second field (which is a reference/object), passed by the iteration manager (as for_each, count_if, ..),
		 * @note   OBJECT_TYPE must be the \b second (value) of the pair: map<whatever-type,OBJECT_TYPE>
		 */
		template <class MAP_KEY>
		void operator() ( std::pair<MAP_KEY,OBJECT_TYPE>& pair_obj ) const {
			if ( &pair_obj.second == NULL ) return;
//			targetContainer.push_back<Variant>( (pair_obj.second.*fAppenderPtr)() );
		 }

	private:
		TARGET_TYPE& targetContainer;	///< output container, such as STL Sequence, wosh::ListT<>, wosh::List
		MethodAppender fAppenderPtr;	///< member function for retrieving object to be added
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ADDER
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////











/*

template <class RUNNER_TYPE, typename VALUE_TYPE>
class Functor_Appender : public std::unary_function<RUNNER_TYPE, VALUE_TYPE> 
 {
	public:
		typedef VALUE_TYPE (RUNNER_TYPE::*MethodAppender)(void) const;

		explicit Functor_Appender(List* output, MethodAppenderSelector fptr )
			: targetContainer(output), fAppenderPtr(fptr) { }

	public:
		bool operator() ( RUNNER_TYPE* object ) const {
			if ( object == NULL ) return;
			targetContainer->add( (object->*fAppenderPtr)() );
		 }

	private:
		List* targetContainer;		///< output container
		MethodAppender fAppenderPtr;	///< member function for retrieving object to be added
};
*/

/**
 * @brief   Appender Functor
 *          widely used in data listing (from internal structure (vector-like) [extract/copy field] to List)
 * @param buffer [out] output buffer
 * @param separator [in] separator 
 * @param fptr [in] method to be called, to retrieve item's value
 ****************************************************************************
 * Sample Usage:
 * @code
 *  std::vector<Object*> objects2;
 *  objects.push_back( new Object(NULL, "asdasd") );
 *  objects.push_back( new Object(NULL, "second") );
 *  List* objs = new List();
 *  for_each( objects.begin(), objects.end(), Functor_Appender_TY<Object, const std::string&, Data>(objs, &Object::getName ) );
 *  for_each( objects.begin(), objects.end(), Functor_Appender_TY<Object, const Permission&, Permission>(objs, &Object::getPermission ) );
 * @endcode
 *
 *
 ****************************************************************************/






















/**
 * @brief   Functor preliminary test, concat string of an object calling a method 
 * @param buffer [out] output buffer
 * @param separator [in] separator 
 * @param fptr [in] method to be called, to retrieve item's value
 ****************************************************************************
 * Sample Usage:
 * @code
 *  std::vector<Object*> objects2;
 *  objects.push_back( new Object(NULL, "asdasd") );
 *  objects.push_back( new Object(NULL, "second") );
 *  std::string result;
 *  for_each( objects.begin(), objects.end(), Functor_ToString_T<Object>(result, ";", &Object::getName ) );
 * @endcode
 *
 *
 ****************************************************************************/
template <class RUNNER_TYPE>
class Functor_ToString_T  {
	public:
		typedef const std::string& (RUNNER_TYPE::*MethodToStringConstRef)(void) const;

		explicit Functor_ToString_T(std::string& buffer, const std::string& separator, MethodToStringConstRef fptr )
			: internalBuffer(buffer), internalSeparator(separator), fToStringPtr(fptr) { }

		bool operator() ( const RUNNER_TYPE* object ) const {
			if ( object == NULL ) return false;
			internalBuffer += (object->*fToStringPtr)() + internalSeparator;
			return true;
		 }

	private:
		std::string& internalBuffer;
		const std::string& internalSeparator;
		MethodToStringConstRef fToStringPtr;

};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/**
 * @brief   Appender Functor
 *          widely used in data listing (from internal structure (vector-like) [extract/copy field] to List)
 * @param buffer [out] output buffer
 * @param separator [in] separator 
 * @param fptr [in] method to be called, to retrieve item's value
 ****************************************************************************
 * Sample Usage:
 * @code
 *  std::vector<Object*> objects2;
 *  objects.push_back( new Object(NULL, "asdasd") );
 *  objects.push_back( new Object(NULL, "second") );
 *  List* objs = new List();
 *  for_each( objects.begin(), objects.end(), Functor_Appender_TY<Object, const std::string&, Data>(objs, &Object::getName ) );
 *  for_each( objects.begin(), objects.end(), Functor_Appender_TY<Object, const Permission&, Permission>(objs, &Object::getPermission ) );
 * @endcode
 *
 ****************************************************************************/
 /*
template <class RUNNER_TYPE, typename RET_TYPE, class RET_PROXY>
class Functor_Appender_TY  {
	public:
		typedef RET_TYPE (RUNNER_TYPE::*MethodAppenderSelector)(void) const;


		explicit Functor_Appender_TY(List* output, MethodAppenderSelector fptr )
			: targetList(output), fSelectorPtr(fptr) { }

		bool operator() ( RUNNER_TYPE* object ) const {
			if ( object == NULL ) return false;
			//targetList->append( new Variant( (object->*fToStringPtr)() ) );
			targetList->push_back<RET_PROXY>( (object->*fSelectorPtr)() );
			return true;
		 }

	private:
		List* targetList;
		MethodAppenderSelector fSelectorPtr;

};

// vector<string> => ListT<Data*>
class Functor_Appender  {
	public:
		explicit Functor_Appender(List* output)
			: targetList(output) { }

		bool operator() ( const std::string& object ) const {
			targetList->append( new Data(object) );
			return true;
		 }

	private:
		List* targetList;
};

template <class RUNNER_TYPE>
class Functor_Appender_T  {
	public:
		typedef const std::string& (RUNNER_TYPE::*MethodToStringConstRef)(void) const;

		explicit Functor_Appender_T(List* output, MethodToStringConstRef fptr )
			: targetList(output), fToStringPtr(fptr) { }

		bool operator() ( RUNNER_TYPE* object ) const {
			if ( object == NULL ) return false;
			targetList->append( new Variant( (object->*fToStringPtr)() ) );
			return true;
		 }

	private:
		List* targetList;
		MethodToStringConstRef fToStringPtr;

};
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// preliminary test
class Functor_ToString_simple  {
	public:
		explicit Functor_ToString_simple(std::string& buffer, const std::string& separator)
			: internalBuffer(buffer), internalSeparator(separator) { }

		bool operator() ( const ISerializable* object ) const {
			if ( object == NULL ) return false;
			internalBuffer += object->toString() + internalSeparator;
			return true;
		 }

	private:
		std::string& internalBuffer;
		const std::string& internalSeparator;
};


//count_if(myVector.begin(), myVector.end(), bind1st(ptr_fun(LengthIsLessThan), "C++!"));



}; // namespace wosh

#endif //__WOSH_Core_Functionals_H__
